﻿using UnityEngine;
using System.Collections;

public class MoveComp 
{
    protected BattleEntity m_pOwner;

    public enum moveType
    {
        Stop,//静止
        Uniform,//匀速运动
        Acceleration,//加速运动
    }
    public moveType m_eType;


    protected Transform m_pTransform;
    public Transform HostTransform
    {
        get { return m_pTransform; }
    }
    //速度大小
    public float m_fSpeed;
    //速度
    public Vector3 m_v3Vdir;
    //加速度
    public Vector3 m_v3accDir;
    //最大速度
    public float m_fMaxSpeed = 10;
    //目标点
    private Vector3 m_v3Target;
    //目标 Transform 跟踪行
    private Transform m_tfTarget;

    private Vector3 m_v3LastDir;

    private bool m_bCheckArrive;

    protected System.Action onArrive;

    public MoveComp(Transform tf,BattleEntity owner)
    {
        m_pTransform = tf;
        m_pOwner = owner;
    }

    public void OnUpdate(float deltaTime)
    {
        if (m_eType == moveType.Stop)
        {
            // do nothing
        }
        else if (m_eType == moveType.Uniform)
        {
            CheckArrive(deltaTime);
            //m_pTransform.transform.position += m_v3Vdir * deltaTime;
        }
        else if (m_eType == moveType.Acceleration)
        {
            CheckArrive(deltaTime);

            m_v3Vdir += m_v3accDir * deltaTime;
            if (m_v3Vdir.magnitude >= m_fMaxSpeed)
                m_v3Vdir = m_v3Vdir.normalized * m_fMaxSpeed;
        }
    }

    //检测是否到达 target点
    public void CheckArrive(float deltaTime) 
    {
        if (m_bCheckArrive &&
            Mathf.Pow(Vector3.Distance(m_pTransform.position, m_v3Target), 2) <= (m_v3Vdir * deltaTime).sqrMagnitude)
        {
            m_pTransform.position = m_v3Target;
            OnArrive();
        }
        else
        {
            if(m_tfTarget != null && m_eType == moveType.Uniform)
            {
                m_v3Target = m_tfTarget.position;
                m_v3Vdir = (m_tfTarget.position - m_pTransform.position).normalized * m_fSpeed;
            }
            m_pTransform.position += m_v3Vdir * deltaTime;
        }

        //if (m_bCheckArrive)
        //{
        //    m_v3LastDir = m_v3Target - m_pTransform.position;
        //    if (Vector3.Dot(m_v3LastDir, m_v3Target - m_pTransform.position) <= 0)
        //    {
        //        m_pTransform.transform.position = m_v3Target;
        //        OnArrive();
        //    }
        //}
    }

    public virtual void OnArrive()
    {
        EntityMessageDispatcher.Instance.SendMessage(MessageId.Arrive, m_pOwner.Id, m_pOwner.Id);
        if (onArrive != null)
            onArrive();
    }

    public void RegOnArrive(System.Action func)
    {
        onArrive = func;
    }
    public void ClearOnArrive()
    {
        onArrive = null;
    }

    //匀速运动
    public void UniformMove(float v,Vector3 target) 
    {
        m_eType = moveType.Uniform;
        m_v3Vdir = Vector3.Normalize(target - m_pTransform.position) * v;
        m_fSpeed = v;
        m_v3Target = target;
        m_tfTarget = null;
        m_bCheckArrive = true;
    }
    public void UniformMoveDir(float v, Vector3 dir)
    {
        m_eType = moveType.Uniform;
        m_fSpeed = v;
        m_v3Vdir = Vector3.Normalize(dir) * v;
        m_tfTarget = null;
        m_bCheckArrive = false;
    }
    public void UniformMoveTransform(float v ,Transform tag)
    {
        m_eType = moveType.Uniform;
        m_fSpeed = v;
        m_tfTarget = tag;
        m_v3Vdir = (tag.position - m_pTransform.position).normalized * v;
        m_bCheckArrive = true;
    }


    //加速运动
    public void AccelerationMove(float accForce,Vector3 accDir,Vector3 target,bool stopVo = true)
    {
        if (stopVo)
            m_v3Vdir = Vector3.zero;

        m_eType = moveType.Acceleration;
        m_v3accDir = accForce * accDir.normalized;
        m_v3Target = target;
        m_tfTarget = null;
        m_bCheckArrive = true;
    }
    public void AccelerationMoveDir(float accForce, Vector3 accDir,bool stopVo = true)
    {
        if (stopVo)
            m_v3Vdir = Vector3.zero;

        m_eType = moveType.Acceleration;
        m_v3accDir = accForce * accDir.normalized;
        m_tfTarget = null;
        m_bCheckArrive = false;
    }

    //停止移动
    public void StopMove() 
    {
        m_eType = moveType.Stop;
        m_v3Vdir = Vector3.zero;
    }

    //获取剩余到达之间
    public float GetRemainingTime()
    {
        if(m_eType == moveType.Uniform)
        {
            return (Vector3.Distance(m_pTransform.position, m_v3Target) / m_v3Vdir.magnitude);
        }
        else if(m_eType == moveType.Acceleration)
        {
            //有问题 需要考虑max Speed
            return 1;
        }
        else
        {
            return 0;
        }
    }
}
